#include "Netdefs.h"
#include <process.h>
#include <string>
#include "SyncWrapper.h"
#include "Protocol.h"
#include <windows.h>
#include <time.h>
using std::string;

#include <iostream>
using std::cout;
using std::endl;

#include "ParkinglotDB.h"

unsigned __stdcall HandleConnection (void* sock);
//unsigned __stdcall HardCoreUnitTest (void* CompletlyUseLess);
void Parser(string s,SyncWrapper* sw,Socket* mysock);
class param
{
	public:
		Socket* s;
		SyncWrapper* sw;
};
int main (int argc, char* argv[]) {
	SyncWrapper sw;
	/*
	sw.CarEnteredUpperCam(20);
	sw.CarParked(20,15,15);
	sw.CarUnparked(16,16);
	sw.CarEnteredGroundCam(2000);
	sw.CarEnteredGroundCam(3000);
	sw.CarEnteredUpperCam(30);
	sw.CarParked(20,15,15);
	sw.CarEnteredUpperCam(40);
	sw.CarEnteredGroundCam(1000);
	sw.CarParked(30,25,15);
	sw.CarParked(40,35,15);
	*/
	SocketServer dbserver(SERVERPORT, MAXCONNECTIONS);
	//cout << "DB main is running";

//	unsigned noNEED;
//	_beginthreadex(0,0,HardCoreUnitTest,0, 0, &noNEED);

	while (1)
	{ 
		// here you can do while ParkingDB->NotDone() or something
		Socket* insock = dbserver.Accept(); // blocking until there's a connection
		param* pp=new param();
		pp->s=insock;
		pp->sw=&sw;
		unsigned ret;
		_beginthreadex(0,0,HandleConnection,pp, 0, &ret);
	}

	return 0;
}

unsigned __stdcall HandleConnection (void* p)
{
	static unsigned num = 0;
	unsigned mynum = ++num;
	param* pp=(param*)p;
	cout << "===DB main polling thread is running=== \n \n";
	Socket* mysock = pp->s;
	cout << "\nAccepted connection: " << mynum << endl;

	while (1) {
		string readline = mysock->ReceiveLine();
		if (readline.empty())
		{
			Sleep(10);//This thing give the cpu a little time to breath
			//just enogh to get to 0% CPU, little bit primitive, but works fine :)
			continue;
		}
		cout << "\nGot line: " << readline;
		mysock->SendLine(string("recieved by DBServer - ")+=readline);
		Parser(readline,pp->sw,mysock);
	}

	delete mysock;

	cout << "Closed connection: " << mynum << endl;

	return 0;
}
unsigned __stdcall HardCoreUnitTest (void* CompletlyUseLess) 
{
	string ip = "127.0.0.1";
	SocketClient *mysock;
	//using namespace Protocol;

	try {
		mysock = new SocketClient(ip, SERVERPORT); // this will have to be changed to command line args
	}
	catch (...) {
		cout << "Couldn't connect to " << ip << endl;
		exit(1);
	}

	cout << "====Unit test is Connected..=== \n" << endl;
	Sleep(100);		Protocol::fc2db_entered(*mysock,1001);
	Sleep(100);		Protocol::fc2db_entered(*mysock,2001);
	Sleep(100);		Protocol::tc2db_enetered(*mysock,21);
	Sleep(100);		Protocol::tc2db_enetered(*mysock,11);
	Sleep(100);		Protocol::tc2db_parked(*mysock,11,15,15);
	Sleep(100);		Protocol::tc2db_parked(*mysock,21,25,15);
	Sleep(100);		Protocol::tc2db_unparked(*mysock,16,14);
	Sleep(100);		Protocol::tc2db_parked(*mysock,11,15,15);
	Sleep(100);		Protocol::tc2db_unparked(*mysock,16,14);
	Sleep(100);		Protocol::tc2db_exited(*mysock,11);
	Sleep(100);
	string s;
	if(ParkinglotDB::instance().WhereIsMyCar(2001,s)==-2)
		cout << "\n===\nTest Passed\n===\n";
	else
		cout << "\n===\nTest Failed\n===\n";
	Sleep(100);		mysock->SendLine("UserInterface connected");
	//string rcv(mysock->ReceiveLine());
	//cout << "Recieved: " << rcv << endl;

	delete mysock;
	return 0;
}